package net.qiqb.core.executing;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import net.qiqb.core.domain.annotation.AttachedAggregate;
import net.qiqb.core.executing.annotation.BusinessIdVoucher;
import net.qiqb.core.executing.annotation.Command;
import net.qiqb.core.executing.annotation.HandleBusiness;
import net.qiqb.core.executing.annotation.ObtainAggregateObject;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class CommandUtil {

    public static Method getObtainAggregateObjectAnnotationMethod(Class<?> commandClazz) {
        if (ClassUtil.isSimpleValueType(commandClazz) || ClassUtil.isJdkClass(commandClazz)) {
            return null;
        }
        final Method[] methods = ReflectUtil.getMethods(commandClazz);
        for (Method method : methods) {
            final ObtainAggregateObject annotation = AnnotationUtil.getAnnotation(method, ObtainAggregateObject.class);
            if (annotation != null) {
                return method;
            }
        }
        return null;
    }

    public static Class<?> getAggregateClass(Class<?> commandClazz) {
        if (ClassUtil.isSimpleValueType(commandClazz) || ClassUtil.isJdkClass(commandClazz)) {
            return null;
        }
        final Command annotation = AnnotationUtil.getAnnotation(commandClazz, Command.class);
        if (annotation != null) {
            return annotation.value();
        }
        return null;
    }


    public static Class<?> getAttachedAggregateRoot(Class<?> commandClazz) {
        if (ClassUtil.isSimpleValueType(commandClazz) || ClassUtil.isJdkClass(commandClazz)) {
            return null;
        }
        final Class<?> aggregateRoot = getAggregateClass(commandClazz);
        final AttachedAggregate annotation = AnnotationUtil.getAnnotation(aggregateRoot, AttachedAggregate.class);
        if (annotation != null) {
            return annotation.value();
        }
        return null;
    }


    public static Method getHandleBusinessAnnotationMethod(Class<?> commandClazz) {
        if (ClassUtil.isSimpleValueType(commandClazz) || ClassUtil.isJdkClass(commandClazz)) {
            return null;
        }
        final Method[] methods = ReflectUtil.getMethods(commandClazz);
        for (Method method : methods) {
            final HandleBusiness annotation = AnnotationUtil.getAnnotation(method, HandleBusiness.class);
            if (annotation != null) {
                return method;
            }
        }
        return null;
    }

    public static Field getBusinessIdVoucherField(Class<?> commandClazz) {
        if (ClassUtil.isSimpleValueType(commandClazz) || ClassUtil.isJdkClass(commandClazz)) {
            return null;
        }
        final Field[] fields = ReflectUtil.getFields(commandClazz);
        for (Field f : fields) {
            final BusinessIdVoucher annotation = AnnotationUtil.getAnnotation(f, BusinessIdVoucher.class);
            if (annotation != null) {
                return f;
            }
        }
        return null;
    }

    public static String getBusinessIdVoucherName(Field field) {
        final BusinessIdVoucher annotation = AnnotationUtil.getAnnotation(field, BusinessIdVoucher.class);
        String name = null;
        if (annotation != null && StrUtil.isNotBlank(annotation.value())) {
            name = annotation.value();
        }
        // 使用名称
        if (name == null) {
            name = field.getName();
        }
        return name;
    }
}
